<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title>js画板</title>
		<style>
			* {
				margin: 0;
				padding: 0;
			}

			html,
			body,
			.container {
				height: 100%;
			}

			#controls {
				padding-left: 20px;
				height: 60px;
				line-height: 60px;
			}

			canvas {
				border: 1px solid #ccc;
				margin-left: 20px;
			}
			#controls li {
				list-style: none;
				display: inline-block;
				margin-right: 10px;
			}
			#img {
				width: 1000px;
				height: 400px;
				background: #eee;
				display: inline-block;
				margin-left: 20px;
			}
			.word {
				margin: 10px 0 10px 20px;
			}
		</style>
	</head>

	<body>
		<div class="container">
			<ul id="controls">
				<li>
					<label for="shape" class="label">选择形状 : </label>
					<select id="shape">
						<option value="rect">矩形</option>
						<option value="line">直线</option>
						<!--<option value="circle">内切圆</option>-->
						<option value="circle">圆</option>
						<!--<option value="circle2">中心圆</option>-->
						<option value="poly">多边形</option>
						<option value="pen">铅笔</option>
						<option value="eraser">橡皮擦</option>
					</select>
				</li>

				<li>
					<label for="color" class="label">选择颜色 : </label>
					<input type="color" id="color" value="#ff0000" />
				</li>
				<li>
					<label for="color" class="label">选择线宽 : </label>
					<input type="number" id="width" value="1" step="1" min="2" max="20" />
				</li>
				<li>
					<label for="shape" class="label">选择方式 : </label>
					<select id="style">
						<option value="stroke">描边</option>
						<option value="fill">填充</option>
					</select>
				</li>
				<li>
					<label for="side" class="label">选择边数 : </label>
					<input type="number" id="side" value="3" min="3" max="20" />
				</li>
				<li>
					<button id="redo">撤销</button>
					<button id="clear">清空</button>
					<button id="save">保存</button>
				</li>
			</ul>
			<div class="word">canvas面板:</div>
			<canvas width="1000px" height="400px"></canvas>
			<div class="word">显示保存的图片:</div>
			<img src="" id="img" alt="" />
		</div>

		<script>
			var canvas = document.querySelector('canvas')
			var canvasObj = canvas.getContext('2d')
			var shape = document.querySelector('#shape')
			var color = document.querySelector('#color')
			var width = document.querySelector('#width')
			var style = document.querySelector('#style')
			var side = document.querySelector('#side')
			var redo = document.querySelector('#redo')
			var save = document.querySelector('#save')
			var clear = document.querySelector('#clear')
			var data = []
			var s = 'rect'
			shape.onchange = function () {
				//获取形状
				s = this.value
			}
			var c = '#f00'
			color.onchange = function () {
				//获取颜色
				c = this.value
			}
			var w = '2'
			width.onchange = function () {
				//获取宽度
				w = this.value
			}
			var st = 'stroke'
			style.onchange = function () {
				//获取绘画方式
				st = this.value
			}
			var sd = '3'
			side.onchange = function () {
				//获取边数
				sd = this.value
			}
			canvas.onmousedown = function (e) {
				//canvas上按下鼠标事件
				var ox = e.offsetX
				var oy = e.offsetY
				var draw = new Draw(canvasObj, {
					color: c,
					width: w,
					style: st,
					side: sd,
				})
				if (s === 'pen') {
					canvasObj.beginPath()
					canvasObj.moveTo(ox, oy)
				}
				canvas.onmousemove = function (e) {
					//移动事件
					var mx = e.offsetX
					var my = e.offsetY
					if (s !== 'eraser') {
						canvasObj.clearRect(0, 0, 1000, 400)
						if (data.length !== 0) {
							canvasObj.putImageData(data[data.length - 1], 0, 0, 0, 0, 1000, 400) //将数据添加到画布中
						}
					}
					draw[s](ox, oy, mx, my, sd)
				}
				document.onmouseup = function () {
					data.push(canvasObj.getImageData(0, 0, 1000, 400)) //获取画布中的数据
					canvas.onmousemove = null
					document.onmouseup = null
				}
			}
			redo.onclick = function () {
				//撤回
				if (data.length == 0) {
					alert('没有可以撤销的内容了')
					return
				}
				canvasObj.clearRect(0, 0, 1000, 400)
				data.pop()
				if (data.length == 0) {
					return
				}
				canvasObj.putImageData(data[data.length - 1], 0, 0, 0, 0, 1000, 400)
			}
			save.onclick = function () {
				//保存
				var r = canvas.toDataURL()
				document.getElementById('img').src = r
			}
			clear.onclick = function () {
				//清除
				canvasObj.clearRect(0, 0, 1000, 400)
				data = []
			}
			class Draw {
				constructor(canvasObj, option) {
					this.canvasObj = canvasObj
					this.color = option.color
					this.width = option.width
					this.style = option.style
				}
				init() {
					//初始化
					this.canvasObj.strokeStyle = this.color
					this.canvasObj.fillStyle = this.color
					this.canvasObj.lineWidth = this.width
				}
				rect(ox, oy, mx, my) {
					this.init()
					this.canvasObj.beginPath()
					this.canvasObj.rect(ox, oy, mx - ox, my - oy)
					this.canvasObj[this.style]()
				}
				line(ox, oy, mx, my) {
					this.init()
					this.canvasObj.beginPath()
					this.canvasObj.moveTo(ox, oy)
					this.canvasObj.lineTo(mx, my)
					this.canvasObj.stroke()
				}
				circle(ox, oy, mx, my) {
					//圆
					this.init()
					this.canvasObj.beginPath()
					var r = Math.sqrt(Math.pow(mx - ox, 2) + Math.pow(my - oy, 2))
					this.canvasObj.arc(ox, oy, r, 0, 2 * Math.PI)
					this.canvasObj[this.style]()
				}
				poly(ox, oy, mx, my, sd) {
					this.init()
					this.canvasObj.save()
					canvasObj.translate(ox, oy)
					this.canvasObj.rotate(Math.PI / 2)
					var angle = Math.PI / sd
					var r = Math.sqrt(Math.pow(mx - ox, 2) + Math.pow(my - oy, 2))
					var x = Math.cos(angle) * r
					var y = Math.sin(angle) * r
					this.canvasObj.beginPath()
					this.canvasObj.moveTo(x, y)
					for (var i = 0; i < sd; i++) {
						this.canvasObj.lineTo(x, -y)
						this.canvasObj.rotate(-angle * 2)
					}
					this.canvasObj[this.style]()
					this.canvasObj.restore()
				}
				pen(ox, oy, mx, my) {
					this.init()
					this.canvasObj.lineTo(mx, my)
					this.canvasObj.stroke()
				}
				eraser(ox, oy, mx, my) {
					console.log(canvas.style)
					console.log(canvas.style.cursor)
					this.canvasObj.clearRect(mx, my, 20, 20)
				}
			}
		</script>
	</body>
</html>
